#include "Car.h"

/**************************************** APP 指令协议 *************************************************************************

*	前进：a			长按:	k
*	后退：b			长按:	m
*	左转：c			长按:	p
*	右转：d			长按:	q
*	停止：e

*	微调左：g
*	微调右：h
*	减速：i
*	加速：j

APP下载地址：
***************************************适用于深圳大夏龙雀科技有限公司APP******************************************************/

uint8_t speed = 80; // 速度
uint8_t sleeptime = 250;//单次控制时间
uint8_t mode = 1; // 0为开启控制，1为关闭

///@brief 初始化小车的运动控制
void Car_Init(void)
{
    Motor_Init();
    Serial_Init();
}

// 小车停止
void Car_Stop(void)
{
    Motor_Stop();
}

///@brief 处理长按时的退出
///@param nowmode 当前控制状态
void ExitLong(char nowmode)
{
    while (1)
    {
        delay_ms(280);
        if (USART_GetFlagStatus(USART3, USART_FLAG_RXNE) == SET)
        {
            RxData = USART_ReceiveData(USART3);
            if (RxData != nowmode) // 小车不是当前状态就退出
            {
                Car_Contorl(RxData);
                break;
            }
        }
        else
        {
            Car_Stop();
            break;
        }
    }
}

///@brief 小车前进
///@param Speed 速度
void Car_Forward(uint8_t Speed)
{
    Motor_SetMotorA_Speed(Speed);
    Motor_SetMotorB_Speed(Speed);
    Motor_SetMotorC_Speed(Speed);
    Motor_SetMotorD_Speed(Speed);
}

///@brief 小车后退
///@param Speed 速度
void Car_Backward(uint8_t Speed)
{
    Motor_SetMotorA_Speed(-Speed);
    Motor_SetMotorB_Speed(-Speed);
    Motor_SetMotorC_Speed(-Speed);
    Motor_SetMotorD_Speed(-Speed);
}

///@brief 小车左转
///@param Speed 速度
void Car_TurnLeft(uint8_t Speed)
{
    Motor_SetMotorA_Speed(-Speed);
    Motor_SetMotorB_Speed(Speed);
    Motor_SetMotorC_Speed(-Speed);
    Motor_SetMotorD_Speed(Speed);
}

///@brief 小车右转
///@param Speed 速度
void Car_TurnRight(uint8_t Speed)
{
    Motor_SetMotorA_Speed(Speed);
    Motor_SetMotorB_Speed(-Speed);
    Motor_SetMotorC_Speed(Speed);
    Motor_SetMotorD_Speed(-Speed);
}

/// @brief 接收小车指令控制小车运动
/// @param command 单个字符指令，g启动，h终止， a前进，b后退，c左转，d右转，e停止，k长按前进，m长按后退，p长按左转，q长按右转，i减速，j加速
void Car_Contorl(char command)
{
    switch (RxData)
    {
    case 'a':
        Car_Forward(speed);
        delay_ms(sleeptime);
        Car_Stop();

        break;
    case 'b':
        Car_Backward(speed);
        delay_ms(sleeptime);
        Car_Stop();

        break;
    case 'c':
        if (speed <= 45)
        {
            Car_TurnLeft(45);
        }
        else
        {
            Car_TurnLeft(speed);
        }

        delay_ms(sleeptime);
        Car_Stop();

        break;
    case 'd':
        if (speed <= 50)
        {
            Car_TurnRight(45);
        }
        else
        {
            Car_TurnRight(speed);
        }

        delay_ms(sleeptime);
        Car_Stop();

        break;
    case 'e':
        Car_Stop();

        break;
    case 'k':
        Car_Forward(speed);
        ExitLong('k');
        break;
    case 'm':
        Car_Backward(speed);
        ExitLong('m');
        break;
    case 'p':
        Car_TurnLeft(speed);
        ExitLong('p');
        break;
    case 'q':
        Car_TurnRight(speed);
        ExitLong('q');
        break;
    case 'g':
        mode = 0;
        break;
    case 'h':
        mode = 1;
        break;
    case 'i':
        speed -= 10;

        if (speed <= 60)
            speed = 60;
        break;
    case 'j':
        speed += 10;

        if (speed >= 100)
            speed = 100;
        break;
    default:
        break;
    }
}

///@brief 小车运行
void Car_Run(void)
{
    while (1)
    {
        // 判断是否接受到数据
        if (USART_GetFlagStatus(USART3, USART_FLAG_RXNE) == SET)
        {
            RxData = USART_ReceiveData(USART3);
        }
        if (mode == 0 || RxData == 'g') // 如果mode为0或者接收到g指令，则进入控制模式
        {
            Car_Contorl(RxData);
            RxData = 0;
        }
    }
}
